package com.muyan.sys.webscoket.server;

import com.muyan.sys.webscoket.interceptor.WebSocketAuthInterceptor;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.netty.channel.ChannelHandler.Sharable;
import java.nio.charset.StandardCharsets;

@Sharable
@Component
public class WebSocketHandshakeHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketHandshakeHandler.class);
    @Autowired
    private WebSocketAuthInterceptor authInterceptor;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;
            String uri = request.uri();
            
            // 只处理 WebSocket 握手请求
            if (uri.startsWith("/ws")) {
                // 从请求头中获取 token
                String authHeader = request.headers().get(HttpHeaderNames.AUTHORIZATION);
                if (authHeader != null && authHeader.startsWith("Bearer ")) {
                    String token = authHeader.substring(7);
                    // 将 token 添加到请求属性中，供认证拦截器使用
                    ctx.channel().attr(io.netty.util.AttributeKey.valueOf("token")).set(token);
                }
                
                // 进行认证
                if (!authInterceptor.authenticate(ctx, request)) {
                    logger.info("Authentication failed, closing connection");
                    
                    // 创建 WebSocket 握手响应
                    WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                        "ws://" + request.headers().get(HttpHeaderNames.HOST) + "/ws",
                        null,
                        false
                    );
                    WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(request);
                    
                    if (handshaker != null) {
                        // 发送握手响应
                        handshaker.handshake(ctx.channel(), request).addListener(future -> {
                            if (future.isSuccess()) {
                                // 握手成功后发送 401 错误并关闭连接
                                WebSocketFrame frame = new CloseWebSocketFrame(
                                    WebSocketCloseStatus.POLICY_VIOLATION,
                                    "401"
                                );
                                ctx.writeAndFlush(frame).addListener(f -> ctx.close());
                            }
                        });
                    } else {
                        WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
                    }
                    return;
                }
                
                logger.info("Authentication successful for user: {}", 
                          ctx.channel().attr(io.netty.util.AttributeKey.valueOf("LoginUser")).get());
            }
        }
        // 继续处理其他消息
        ctx.fireChannelRead(msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("Handshake error", cause);
        ctx.close();
    }
} 